/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.SalesForecast;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import managedbean.Workspace.WorkspaceManagerBean;
import merlion.common.entity.Staff;
import merlion.common.session.stateless.SystemUserSessionBeanLocal;
import merlion.common.util.Consts;
import merlion.mrp.ppm.entity.IndexNValue;
import merlion.mrp.ppm.entity.IndivForecast;
import merlion.mrp.ppm.entity.SalesForecast;
import merlion.mrp.ppm.entity.UpdateIndiv;
import merlion.mrp.ppm.session.SalesForecastingSessionLocal;

/**
 *
 * @author Zhang Ying
 */
@ManagedBean(name = "sfMgmtManagerBean")
@ViewScoped
public class SalesForecastMgmtManagerBean {

    public static final String SELECTED_SF = "SelectedSF";
    public static final String SELECT_EDIT_SF = "SelectedEditSF";
    public static final String EDIT_SF = "EditSF";
    public static final String UPDATE_SF = "UpdateSF";
    @ManagedProperty(value = "#{workspaceManagerBean}")
    private WorkspaceManagerBean workspaceManagerBean;
    @EJB
    private SystemUserSessionBeanLocal suSession;
    @EJB
    private SalesForecastingSessionLocal salesForecastSession;
    // viewSalesForecast page
    private String selectedSFId;
    private SalesForecast selectedSF;
    private SalesForecast viewedSF;
    private Collection<SalesForecast> allSalesForecast;
    // viewSalesForecastDetail page
    private List<Long> updatedTimes;
    private Long selectedUpdatedId;
    private ArrayList<String> labels;
    private ArrayList<Integer> counterForProduct;
    // for edit
    private SalesForecast editSF;
    private String editSFID;

    /** Creates a new instance of SalesForecastMgmtManagerBean */
    public SalesForecastMgmtManagerBean() {
        //selectedUpdatedId = new Long(0);
        counterForProduct = new ArrayList<Integer>();
        for (int i = 0; i < 4; i++) {
            counterForProduct.add(new Integer(i));
        }
    }

    // for viewSalesForecast page
    public SalesForecast getViewedSF() {
        return viewedSF;
    }

    public void setViewedSF(SalesForecast viewedSF) {
        this.viewedSF = viewedSF;
        selectedSFId = viewedSF.getSfIdStr();
    }

    public String redirectToViewSFDetail() {
        if (selectedSFId == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Please select sales forecast."));
            return null;
        }
        if (!salesForecastSession.checkValidForecastId(selectedSFId)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Your forecast id is not valid."));
            return null;
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(SELECTED_SF);
        selectedSF = salesForecastSession.getSalesForecastFromIdStr(selectedSFId);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(SELECTED_SF, selectedSF);
        //return getRedirectPath(Consts.VIEW_SALES_FORECAST_PATH + "Detail") + "&sfId=" + selectedSFId;
        return getRedirectPath(Consts.VIEW_SALES_FORECAST_PATH + "Detail");
    }

    public Collection<SalesForecast> getAllSalesForecast() {
        if (allSalesForecast == null) {
            allSalesForecast = salesForecastSession.getAllSalesForecast();
        }
        return allSalesForecast;
    }

    public void setAllSalesForecast(Collection<SalesForecast> allSalesForecast) {
        this.allSalesForecast = allSalesForecast;
    }

    public SalesForecast getSelectedSF() {
        if (selectedSF == null) {
            SalesForecast temp = (SalesForecast) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(SELECTED_SF);
            if (temp != null) {
                selectedSF = temp;
                //FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(SELECTED_SF);
            }
//            HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
//            selectedSFId = request.getParameter("sfId");
//            if (selectedSFId != null) {
//                selectedSF = salesForecastSession.getSalesForecastFromIdStr(selectedSFId);
//            }
        }
        return selectedSF;
    }

    public void setSelectedSF(SalesForecast selectedSF) {
        this.selectedSF = selectedSF;
    }

    public String getSelectedSFId() {
        return selectedSFId;
    }

    public void setSelectedSFId(String selectedSFId) {
        this.selectedSFId = selectedSFId;
    }

    // for general purpose
    private String getRedirectPath(String path) {
        return path + "?faces-redirect=true";
    }

    public ArrayList<Integer> getCounterForProduct() {
        return counterForProduct;
    }

    public void setCounterForProduct(ArrayList<Integer> counterForProduct) {
        this.counterForProduct = counterForProduct;
    }

    public WorkspaceManagerBean getWorkspaceManagerBean() {
        return workspaceManagerBean;
    }

    public void setWorkspaceManagerBean(WorkspaceManagerBean workspaceManagerBean) {
        this.workspaceManagerBean = workspaceManagerBean;
    }
    
    public String returnProductName(Integer pid) {
        if (pid.equals(0)) {
            return Consts.ProductType.BAR_A.getText();
        } else if (pid.equals(1)) {
            return Consts.ProductType.BAR_B.getText();
        } else if (pid.equals(2)) {
            return Consts.ProductType.BAR_C.getText();
        } else {
            return Consts.ProductType.BAR_D.getText();
        }
    }

    // viewSalesForecast detail page
    public List<Long> getUpdatedTimes() {
        List<UpdateIndiv> uis = (List<UpdateIndiv>) getSelectedSF().returnProductIndivForecast(0).getUpdateIndivs();
        if (uis == null || uis.isEmpty()) {
            updatedTimes = new ArrayList<Long>();
            updatedTimes.add(new Long(0)); // 0 stands for the orginal copy
        } else {
            updatedTimes = new ArrayList<Long>();
            for (int i = 0; i < uis.size() + 1; i++) {
                updatedTimes.add(new Long(i)); // 0 stands for the orginal copy
            }
        }
        return updatedTimes;
    }

    public void setUpdatedTimes(List<Long> updatedTimes) {
        this.updatedTimes = updatedTimes;
    }

    public String selectUpdatedVersionId(Long id) {
        setSelectedUpdatedId(id);
        return null;
    }

    public String returnUpdatedTime(Long id) {
        if (id.intValue() == 0) {
            return selectedSF.getFormattedDay();
        } else {
            UpdateIndiv ui = selectedSF.returnProductIndivForecast(0).returnUpdateIndivs(id.intValue() - 1);
            if (ui == null) {
                return null;
            } else {
                return ui.getFormattedDay();
            }
        }
    }

    public String returnUpdatedOrOrigTitle(Long id) {
        if (id.intValue() == 0) {
            return "Original Copy";
        } else {
            return "Updated Version " + id;
        }
    }

    public Long getSelectedUpdatedId() {
        return selectedUpdatedId;
    }

    public void setSelectedUpdatedId(Long selectedUpdatedId) {
        this.selectedUpdatedId = selectedUpdatedId;
    }

    public ArrayList<Long> returnSelectedBaseProjection(Integer productId) {
        ArrayList<Long> result = new ArrayList<Long>();
        for (IndexNValue inl : selectedSF.returnProductIndivForecast(productId.intValue()).getBaseProjectionSelected()) {
            result.add(inl.getLongValue());
        }
        return result;
    }

    public ArrayList<Long> returnSelectedPromotion(Integer productId) {
        ArrayList<Long> result = new ArrayList<Long>();
        if (selectedUpdatedId == null || selectedUpdatedId.intValue() == 0) {
            for (IndexNValue inl : selectedSF.returnProductIndivForecast(productId.intValue()).getPromotionList()) {
                result.add(inl.getLongValue());
            }
        } else {
            for (IndexNValue inl : selectedSF.returnProductIndivForecast(productId.intValue()).returnUpdateIndivs(selectedUpdatedId.intValue() - 1).getPromotionList()) {
                result.add(inl.getLongValue());
            }
        }
        return result;
    }

    public ArrayList<Long> returnSelectedHumanAdj(Integer productId) {
        ArrayList<Long> result = new ArrayList<Long>();
        if (selectedUpdatedId == null || selectedUpdatedId.intValue() == 0) {
            for (IndexNValue inl : selectedSF.returnProductIndivForecast(productId.intValue()).getHumanAdjustList()) {
                result.add(inl.getLongValue());
            }
        } else {
            for (IndexNValue inl : selectedSF.returnProductIndivForecast(productId.intValue()).returnUpdateIndivs(selectedUpdatedId.intValue() - 1).getHumanAdjustList()) {
                result.add(inl.getLongValue());
            }
        }
        return result;
    }

    public ArrayList<Long> returnSelectedFinal(Integer productId) {
        ArrayList<Long> result = new ArrayList<Long>();
        if (selectedUpdatedId == null || selectedUpdatedId.intValue() == 0) {
            for (IndexNValue inl : selectedSF.returnProductIndivForecast(productId.intValue()).getFinalValues()) {
                result.add(inl.getLongValue());
            }
        } else {
            for (IndexNValue inl : selectedSF.returnProductIndivForecast(productId.intValue()).returnUpdateIndivs(selectedUpdatedId.intValue() - 1).getFinalValues()) {
                result.add(inl.getLongValue());
            }
        }
        return result;
    }

    public ArrayList<String> getLabels() {
        labels = new ArrayList<String>();
        if (getSelectedSF().getStartPeriodMonth() < 7) {
            labels.add(Consts.JAN);
            labels.add(Consts.FEB);
            labels.add(Consts.MAR);
            labels.add(Consts.APR);
            labels.add(Consts.MAY);
            labels.add(Consts.JUN);
        } else {
            labels.add(Consts.JUL);
            labels.add(Consts.AUG);
            labels.add(Consts.SEP);
            labels.add(Consts.OCT);
            labels.add(Consts.NOV);
            labels.add(Consts.DEC);
        }
        return labels;
    }

    public void setLabels(ArrayList<String> labels) {
        this.labels = labels;
    }

    // for select edit page
    public SalesForecast getEditSF() {
        if (editSF == null) {
            SalesForecast temp = (SalesForecast) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(SELECT_EDIT_SF);
            if (temp != null) {
                editSF = temp;
            }
        }
        return editSF;
    }

    public void setEditSF(SalesForecast editSF) {
        this.editSF = editSF;
        this.editSFID = editSF.getSfIdStr();
    }

    public String getEditSFID() {
        return editSFID;
    }

    public void setEditSFID(String editSFID) {
        this.editSFID = editSFID;
    }

    public String redirectToEditOrUpdatePage() {
        // check the selected SF
        if (editSFID == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Please select sales forecast."));
            return null;
        }
        if (!salesForecastSession.checkValidForecastId(editSFID)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Your forecast id is not valid."));
            return null;
        }
        
        // check whether I am the one created it -> changed to: check whether you have the access right
//        Staff s = suSession.getStaff(workspaceManagerBean.getCurrentStaff().getId());
//        if (!s.getSalesForecasts().contains(editSF)){
//            FacesContext.getCurrentInstance().addMessage(null,
//                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Sorry, you are not the creator of this forecast and cannot edit or update it."));
//            return null;
//        }
        
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(SELECT_EDIT_SF);

        editSF = salesForecastSession.getSalesForecastFromIdStr(editSFID);
        if (editSF.getSops() == null || editSF.getSops().isEmpty()) {
            return redirectToEditPage();
        } else {
            return redirectToUpdatePage();
        }
        //testing for update:
        //return redirectToUpdatePage();
    }

    public String redirectToEditPage() {
        //return getRedirectPath(Consts.EDIT_SALES_FORECAST_PATH + "Edit")+"&sfId="+selectedSFId;
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(EDIT_SF);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(EDIT_SF, editSF);
        return getRedirectPath(Consts.EDIT_SALES_FORECAST_PATH + "Edit");
    }

    public String redirectToUpdatePage() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(UPDATE_SF);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(SalesForecastUpdateManagerBean.NEW_UPDATE_INDIVS);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(UPDATE_SF, editSF);
        // create new list of updateIndiv
        Calendar calendar = Calendar.getInstance();
        Date date = calendar.getTime();
        Timestamp currentTime = new Timestamp(date.getTime());

        ArrayList<UpdateIndiv> newUpdateIndivs = new ArrayList<UpdateIndiv>();
        
        int updateTimes;
        if (editSF.returnProductIndivForecast(0).getUpdateIndivs() == null || editSF.returnProductIndivForecast(0).getUpdateIndivs().isEmpty()){
            updateTimes = 0;
        } else {
            updateTimes = editSF.returnProductIndivForecast(0).getUpdateIndivs().size();
        }
        
        for (int i = 0; i < 4; i++) {
            UpdateIndiv temp = new UpdateIndiv(currentTime,updateTimes);
            newUpdateIndivs.add(temp);

            // check to retrieve from original or from update versions
            boolean fromOriginal = false;
            if (editSF.returnProductIndivForecast(i).getUpdateIndivs() == null || editSF.returnProductIndivForecast(i).getUpdateIndivs().isEmpty()) {
                fromOriginal = true;
            }
            if (fromOriginal) {
                for (int j = 0; j < 6; j++) {
                    IndivForecast indiv = editSF.returnProductIndivForecast(i);
                    newUpdateIndivs.get(i).getPromotionList().get(j).setLongValue(indiv.getPromotionList().get(j).getLongValue());
                    newUpdateIndivs.get(i).getHumanAdjustList().get(j).setLongValue(indiv.getHumanAdjustList().get(j).getLongValue());
                    newUpdateIndivs.get(i).getFinalValues().get(j).setLongValue(indiv.getFinalValues().get(j).getLongValue());
                }
            } else {
                int size = editSF.returnProductIndivForecast(i).getUpdateIndivs().size();
                for (int j = 0; j < 6; j++) {
                    UpdateIndiv indiv = editSF.returnProductIndivForecast(i).returnUpdateIndivs(size - 1);
                    newUpdateIndivs.get(i).getPromotionList().get(j).setLongValue(indiv.getPromotionList().get(j).getLongValue());
                    newUpdateIndivs.get(i).getHumanAdjustList().get(j).setLongValue(indiv.getHumanAdjustList().get(j).getLongValue());
                    newUpdateIndivs.get(i).getFinalValues().get(j).setLongValue(indiv.getFinalValues().get(j).getLongValue());
                }
            }
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(SalesForecastUpdateManagerBean.NEW_UPDATE_INDIVS, newUpdateIndivs);
        return getRedirectPath(Consts.EDIT_SALES_FORECAST_PATH + "Update");
    }
}
